import React, {
    Fragment,
    PureComponent
} from 'react';

import RNIap, {
    SubscriptionPurchase
} from 'react-native-iap';

import {
    View,
    Text,
    ScrollView,
    Dimensions,
    StyleSheet,
    ImageBackground
} from 'react-native';

const {
    height
} = Dimensions.get('screen');

import {
    Tip,
    Press,
    Button,
    PayPal,
    Radio,
    Loading
} from './../../components';

import Ajax from "../../http";
import * as Const from './../../const';
import connect from './../../utils/connect';

import iapAction from './../../state/actions/iap';
import userAction from './../../state/actions/user';
import * as iapTypes from './../../state/types/iap';
import * as userTypes from './../../state/types/user';
import close_icon from './../../images/iap/back.png';

interface Props {
    iap: any,
    userActions:any,
    iapActions: any,
    onSuccess:Function,
    onDialogClose:Function
}

interface State {
    index: number,
    payment:number
}

import {
    onEvent,
    events
} from './../../utils/analytics';

import Swipe from 'react-native-swiper';

import img_1 from './../../images/iap/pic-1.png';
import img_2 from './../../images/iap/pic-2.png';
import img_3 from './../../images/iap/pic-3.png';

const banners = [
    {
        source: img_1,
        title: `Find out who match you`,
        text: `Check your mutual match`
    },
    {
        source: img_2,
        title: `Send unlimited messages`,
        text: `Chat with others at will`
    },
    {
        source: img_3,
        title: `Control who can see you`,
        text: `Only certain types of users can see you`
    }
]

const paySuccessMessage = `The payment successfully.`;
const payFailMessage = `Sorry, the payment failed. Please try again.`;

@connect([`iap`], {
    iapActions: iapAction,
    userActions:userAction
})
class Upgrade extends PureComponent<Props, State> {
    state = {
        index: 0,
        payment:0
    }

    static defaultProps = {
        iap:{},
        iapActions:{},
        userActions:{},
        onSuccess:() => null,
        onDialogClose:() => null
    }

    checkCount:number = 0;

    get iapActions() {
        const {
            iapActions
        } = this.props;
        return iapActions;
    }

    get userActions() {
        const {
            userActions
        } = this.props;
        return userActions;
    }

    get upgradePlans() {
        const {
            iap
        } = this.props;
        const {
            plans
        } = iap;
        return plans || {};
    }

    get payments() {
        return Object.keys(
            this.upgradePlans
        )
    }

    get planMaps() {
        return this.payments.map(key => (
            this.upgradePlans[key] || []
        ))
    }

    get plans() {
        const {
            payment
        } = this.state;
        const {
            list = []
        } = this.planMaps[payment] || {};
        return list;
    }

    get selectedPlan() {
        const {
            index
        } = this.state;
        return this.plans[index];
    }

    componentDidMount() {
        RNIap.initConnection();
        this.iapActions[
            iapTypes.getGoldPlans
        ]();
    }

    componentWillUnmount(){
        RNIap.endConnectionAndroid();
    }

    private onClose = () => {
        this.props.onDialogClose();
    }

    private _onChoose = (i:number) => {
        this.setState({
            index:i
        })
    }

    private _renderItem = (item:any, i:number) => {
        const {
            index
        } = this.state;
        const {
            price,
            month,
            currencySymbol
        } = item;
        const _styles = [];
        const _selected = index === i;
        const _end = (i + 1) % 3 === 0;
        if (_end) {
            _styles.push(styles.endItem)
        }
        if (_selected) {
            _styles.push(styles.selectedItem);
        }
        const _curTime = month < 1? ~~(month*28):month;

        return (
            <Press
                key={i}
                value={i}
                onPress={this._onChoose}
                style={[styles.planItem, _styles]}
            >
                <Text style={styles.monthStyle}>
                    <Text style={styles.month}>
                        {_curTime}
                    </Text>
                    <Text style={styles.small}>
                        {month < 1 ? `Day`:`Month`}
                    </Text>
                </Text>
                <View style={styles.itemContent}>
                    <Text style={styles.price}>
                        {currencySymbol} {price}
                    </Text>
                </View>
            </Press>
        )
    }

    get planIds() {
        return this.plans.map(({planId}:any) => planId);
    }

    private checkPays = async () => {
        try {
            return await RNIap.getSubscriptions(
                this.planIds
            )
        }
        catch (e) {
            return Promise.reject(e)
        }
    }

    //拉起支付
    private _onLaunchPay = async () => {
        const {
            payment
        } = this.state;

        const {
            planId
        } = this.selectedPlan;

        const type = (
            this.payments[payment]
        )

        onEvent(events[`点击支付按钮`],{
            source:`upgrade`
        })

        switch (type){
            case 'paypalPay':return this._launchPayPalPay(planId)
            case 'googlePay':return this._launchGooglePay(planId)
        }
    }

    //payPal支付
    private _launchPayPalPay = async (
        planId:string
    ) => {
        const para:any = {
            planId:planId,
            type:'subscribe'
        }
        try {
            this._onSavePayPalResult(
                await PayPal.buy(para)
            )
        }
        catch (e) {
            Tip.warm({
                message: e.message
            })
        }
    }

    //google支付
    private _launchGooglePay = async (
        planId:string
    ) => {
        Loading.show();
        try {
            await this.checkPays();
            this._onSaveResult(
                await RNIap.requestSubscription(planId)
            )
        }
        catch (e) {
            Loading.close();
            Tip.warm({
                message:e.message
            })
        }
    }

    //保存payPal支付结果
    private _onSavePayPalResult = async (
        token:string
    ) => {

        Loading.show();

        const _para = {
            token:token
        }

        const payType = `payPal`;

        onEvent(events[`支付返回成功`],{
            source:`upgrade`,
            method:payType
        });

        try {
            await Ajax.post(
                `paypal/subscribe/agreement`,
                _para
            )
            this._onCheckResult(token,payType);
        }
        catch (e) {
            this._onPayFail(payType);
        }
    }

    //保存支付结果
    private _onSaveResult = async (
        res:SubscriptionPurchase
    ) => {
        const {
            productId =``,
            transactionId =``,
            transactionReceipt =``
        } = res;

        const para:any = {
            transactionId,
            transactionReceipt,
            productIdentifier:productId
        }

        const payType = `googlePay`;

        onEvent(events[`支付返回成功`],{
            source:`upgrade`,
            method:payType
        });

        try {
            await this.iapActions[
                iapTypes.savePayResult
            ](para);
            //检测支付结果
            this._onCheckResult(
                transactionId, payType
            )
        }
        catch (e) {
            this._onPayFail(payType);
        }
    }

    private _checkPayPalPid = (token:string) => {
        return Ajax.get(`paypal/paid`,{
            transactionId:token
        })
    }

    //检测结果
    private _onCheckResult = async (
        transactionId:string,
        paymentType:string
    ) => {
        this.checkCount++;
        try {
            const _action = paymentType === `payPal` ?
                this._checkPayPalPid:
                await this.iapActions[
                    iapTypes.checkPayResult
                 ]
            const {
                payStatus,
                membership
            } = await _action(
                transactionId
            )
            switch (payStatus) {
                case 'fail':this._onPayFail(paymentType);break;
                case 'success':this._onPaySuccess(membership,paymentType);break;
                case 'wait':this._onCheckRetry(transactionId,paymentType);break
            }
        }
        catch (e) {
            this._onPayFail(paymentType);
        }
    }

    //支付失败
    private _onPayFail = (payType:string) => {
        Loading.close();
        this.checkCount = 0;
        Tip.warm({
            message:payFailMessage
        })
        onEvent(events[`后端返回支付失败`],{
            source:`upgrade`,
            method:payType
        })
    }

    //检测重试
    private _onCheckRetry = (
        transactionId:string,
        paymentType:string
    ) => {
        //如果大于12次
        if(this.checkCount >=12) {
            return this._onPayFail(paymentType);
        }
        //间隔5s
        setTimeout(() => {
            this._onCheckResult(
                transactionId,paymentType
            )
        },5000)
    }

    //支付成功
    private _onPaySuccess = async (
        membership:string,
        payType:string
    ) => {
        this.checkCount = 0;
        const {
            onSuccess
        } = this.props;
        try {
            await this.userActions[
                userTypes.loginUser
            ]()
        }
        catch (e) {}
        Loading.close();
        Tip.success({
            message:paySuccessMessage
        })
        this.onClose();
        onSuccess(membership);
        onEvent(events[`后端返回支付成功`],{
            source:`upgrade`,
            method:payType
        })
    }

    private onChangePay = (i:number) => {
        this.setState({
            payment:i
        })
    }

    render() {
        const {
            payment
        } = this.state;
        return (
            <Fragment>
                <View style={styles.container}>
                    <View style={styles.header}>
                        <Press
                            source={close_icon}
                            onPress={this.onClose}
                            style={styles.closeButton}
                        />
                    </View>
                    <View style={styles.bannerStyle}>
                        <Swipe>
                            {banners.map((item:any,i:number) => {
                                return (
                                    <ImageBackground
                                        key={i}
                                        source={item.source}
                                        style={styles.bannerItem}
                                    >
                                        <View style={styles.bannerContent}>
                                            <Text style={styles.title}>
                                                {item.title}
                                            </Text>
                                            <Text style={styles.textStyle}>
                                                {item.text}
                                            </Text>
                                        </View>
                                    </ImageBackground>
                                )
                            })}
                        </Swipe>
                    </View>
                    <ScrollView contentContainerStyle={styles.content}>
                        <View style={styles.planStyle}>
                            {this.plans.map(this._renderItem)}
                        </View>
                        <View style={styles.payMethods}>
                            {this.planMaps.map((item,i) => {
                                return (
                                    <Press
                                        key={i}
                                        value={i}
                                        onPress={this.onChangePay}
                                        style={styles.payMethodItem}
                                    >
                                        <Radio checked={i===payment}/>
                                        <Text style={styles.methodName}>
                                            {item.name}
                                        </Text>
                                    </Press>
                                )
                            })}
                        </View>
                        <Button
                            title="Continue to pay"
                            style={styles.payButton}
                            onPress={this._onLaunchPay}
                            disabled={!this.plans.length}
                            titleStyle={{color:`#323541`}}
                        />
                        <Text style={styles.tip}>
                            Christian apologist, survivalist.
                            I’m energetic and faithful. Looking for a woman whose seeking a long term relationship and loves God.
                        </Text>
                    </ScrollView>
                </View>
            </Fragment>
        )
    }
}

export default Upgrade;


const styles = StyleSheet.create({
    container:{
        borderRadius:8,
        overflow:`hidden`,
        alignSelf:`center`,
        backgroundColor:`#fff`,
        borderTopLeftRadius:16,
        borderTopRightRadius:16,
        width:350 * Const.rem*.95
    },
    header:{
        left:0,
        top:0,
        zIndex:99,
        position:`absolute`
    },
    bannerStyle:{
       height:212
    },
    bannerItem:{
        flex:1
    },
    bannerContent:{
        left:0,
        right:0,
        bottom:52,
        alignItems:`center`,
        position:`absolute`
    },
    closeButton:{
        width:56,
        height:56,
        alignItems:`center`,
        justifyContent:`center`
    },
    content:{
        paddingBottom:36,
        paddingHorizontal:16
    },
    titleContent:{
        paddingHorizontal:4,
        paddingBottom:16
    },
    title:{
        fontSize:24,
        color:`#fff`,
        lineHeight:36,
        fontWeight:`bold`
    },
    textStyle:{
        fontSize:16,
        color:`#fff`
    },
    planStyle: {
        paddingVertical:16,
        flexWrap: `wrap`,
        marginBottom:-10,
        flexDirection: `row`
    },
    planItem: {
        height: 110,
        width: `30%`,
        borderRadius: 8,
        marginBottom: 10,
        borderWidth: 2,
        marginRight:`5%`,
        justifyContent:`center`,
        borderColor: `#f9b0ae`
    },
    endItem: {
        marginRight: 0
    },
    month: {
        fontSize: 14,
        color: `#333`,
        textAlign: `center`
    },
    small: {
        fontSize: 14,
        color: `#333`,
    },
    price: {
        fontSize: 18,
        color: `#333`,
        fontWeight:`bold`
    },
    itemContent: {
        alignItems: `center`
    },
    tip: {
        fontSize: 14,
        color: `#8A92AE`,
        lineHeight: 21,
        marginTop: 20
    },
    selectedItem: {
        borderColor: Const.color,
        backgroundColor: `#fff`
    },
    payButton:{
        marginTop:0,
        backgroundColor:`#FFCA00`
    },
    payMethodItem:{
        marginBottom:6,
        flexDirection:`row`,
        alignItems:`center`
    },
    payMethods:{
        marginBottom:16,
        borderRadius:4,
        paddingVertical:8
    },
    methodName:{
        fontSize:16,
        color:`#333`,
        paddingLeft:4
    },
    PayTitle:{
        fontSize:16,
        color:`#fff`,
        marginBottom:6
    },
    monthStyle:{
        textAlign:`center`,
        marginBottom:8
    }
}) as any;